package com.jintian.smart.kernel.flowable.flowable.cmd;

import java.util.Map;

import com.jintian.smart.kernel.common.util.StringUtil;
import org.flowable.common.engine.impl.el.ExpressionManager;
import org.flowable.common.engine.impl.el.VariableContainerWrapper;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.ManagementService;
import org.flowable.engine.impl.util.CommandContextUtil;

public class ExpressCalcCmd implements Command<Object> {
    private String conditionExpression;
    private Map<String, Object> data;

    public ExpressCalcCmd(String conditionExpression, Map<String, Object> data) {
        this.conditionExpression = conditionExpression;
        this.data = data;
    }

    public static boolean isExpression(String expression) {
        String trimExpr = StringUtil.trim(expression);
        if (StringUtil.isBlank(trimExpr)) {
            return false;
        }
        if (trimExpr.startsWith("${") && trimExpr.endsWith("}")) {
            return true;
        }
        return false;
    }

    @Override
    public Object execute(CommandContext commandContext) {
        ExpressionManager expressionManager = CommandContextUtil.getProcessEngineConfiguration(commandContext).getExpressionManager();
        String c = StringUtil.trim(conditionExpression);
        if (!c.startsWith("${")) {
            c = "${" + c + "}";
        }
        org.flowable.common.engine.api.delegate.Expression expression = expressionManager.createExpression(c);
        Object ret = expression.getValue(new VariableContainerWrapper(data));
        return ret;
    }

    public static Object calculate(ManagementService managementService, String expression, Map<String, Object> context) {
        return managementService.executeCommand(new ExpressCalcCmd(expression, context));
    }

    public static boolean calculateBoolean(ManagementService managementService, String expression, Map<String, Object> context) {
        return calculateBoolean(managementService, expression, context, false);
    }

    public static boolean calculateBoolean(ManagementService managementService, String expression, Map<String, Object> context, boolean nullAsTrue) {
        Object result = calculate(managementService, expression, context);
        if (result == null) {
            return nullAsTrue;
        }
        return ((Boolean) result).booleanValue();
    }
}
